package com.fangmao.a19_io;

import android.os.Build;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.RandomAccessFile;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;

import androidx.annotation.RequiresApi;
import okio.Buffer;
import okio.Okio;
import okio.Source;

/**
 * nio 只有网络才可以非阻塞，文件是不可以阻塞的
 */
public class Main {
    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    public static void main(String[] args) {
//        ioWrite();
//        ioRead();
//        ioFlush();
//        ioCopy();
//        ioSocket();
//        nio1();
//        okio1();
        okio2();
    }

    private static void ioWrite() {
        OutputStream outputStream = null;
        try {
            outputStream = new FileOutputStream("./19_io/text.txt");
            outputStream.write('a');
            outputStream.write('b');
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    private static void ioRead() {
        try (InputStream inputStream = new FileInputStream("./19_io/text.txt");
             InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
             BufferedReader bufferedReader = new BufferedReader(inputStreamReader)) {
            System.out.println(bufferedReader.readLine());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    private static void ioFlush() {
        try (OutputStream outputStream = new FileOutputStream("./19_io/text.txt");
             OutputStreamWriter writer = new OutputStreamWriter(outputStream);
             BufferedWriter bufferedWriter = new BufferedWriter(writer)) {
            bufferedWriter.write("ssssssssssssssssss");
            bufferedWriter.write('a');
            bufferedWriter.write('b');
            //放在try里面，自动关闭的话，可以不flush
//            bufferedWriter.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    private static void ioCopy() {
        try (InputStream inputStream = new FileInputStream("./19_io/text.txt");
             OutputStream outputStream = new FileOutputStream("./19_io/new_text.txt")) {
            byte[] data = new byte[3];
            int read = 0;
            while ((read = inputStream.read(data)) != -1) {
                outputStream.write(data, 0, read);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void ioSocket() {
        try {
            ServerSocket serverSocket = new ServerSocket(800);
            Socket socket = serverSocket.accept();
            BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            String data;
            while ((data = reader.readLine()) != null) {
                writer.write(data);
                writer.flush();
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void nio1() {
        try {
            RandomAccessFile file = new RandomAccessFile("./19_io/text.txt", "r");
            FileChannel channel = file.getChannel();
            ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
            channel.read(byteBuffer);
//            byteBuffer.limit(byteBuffer.position());
//            byteBuffer.position(0);
            byteBuffer.flip();//等同于上面两行
            System.out.println(Charset.defaultCharset().decode(byteBuffer));
            byteBuffer.clear();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    @RequiresApi(api = Build.VERSION_CODES.N)
    private static void nio2() {
        ServerSocketChannel serverSocketChannel = null;
        try {
            serverSocketChannel = ServerSocketChannel.open();
            serverSocketChannel.bind(new InetSocketAddress(8080));
//            serverSocketChannel.configureBlocking(false);//设为非阻塞式
            SocketChannel socketChannel = serverSocketChannel.accept();
            ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
            while (socketChannel.read(byteBuffer) != -1) {
                byteBuffer.flip();

                socketChannel.write(byteBuffer);


                byteBuffer.clear();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    private static void okio1() {
        try (Source source = Okio.buffer(Okio.source(new File("./19_io/text.txt")))) {
            Buffer buffer = new Buffer();
            source.read(buffer, 1024);

            System.out.println(buffer.readUtf8());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    private static void okio2() {

        Buffer buffer = new Buffer();
        //作为一个外包对象，和传统的IO进行对接
        try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(buffer.outputStream())) {
            objectOutputStream.writeUTF("abc");
            objectOutputStream.writeBoolean(true);
            objectOutputStream.writeChar('0');
            objectOutputStream.flush();
            ObjectInputStream objectInputStream = new ObjectInputStream(buffer.inputStream());
            System.out.println(objectInputStream.readUTF());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
